package com.benshou.bcss.common.jackson.config;

import com.benshou.bcss.common.jackson.JacksonSerializeCustomizer;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.Serial;
import java.util.List;

/**
 * Jackson 配置
 *
 * @author <a href="mailto:liuzhenbang@benshou.com">Liu Zhenbang</a>
 */
@Configuration
public class JacksonConfig {

    /**
     * @param customizers 列表：Jackson 自定义序列化 Bean
     * @return Jackson 自定义构建序列化对象
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(
            List<JacksonSerializeCustomizer> customizers) {
        return builder -> {
            if (!customizers.isEmpty()) {
                // 根据参数，替换为自定义的序列化器
                var customizationModule = new SimpleModule();
                customizationModule.setSerializerModifier(new BeanSerializerModifier() {
                    @Override
                    public List<BeanPropertyWriter> changeProperties(
                            SerializationConfig config,
                            BeanDescription beanDesc,
                            List<BeanPropertyWriter> beanProperties) {
                        if (beanProperties != null) {
                            beanProperties.forEach(writer -> {
                                for (var customizer : customizers) {
                                    var serializer = customizer.tryCreateSerializer(
                                            config, beanDesc, beanProperties, writer);

                                    if (serializer != null) {
                                        writer.assignSerializer(serializer);
                                        return;
                                    }
                                }});
                        }

                        return beanProperties;
                    }

                    @Serial
                    private static final long serialVersionUID = -9087890213036568098L;
                });

                builder.modulesToInstall(customizationModule);
            }
        };
    }
}
